package itheima06;
/*
     解决方案: 使用同步技术

    同步方法
        1.作用: 解决线程安全问题的
        2.格式:

            修饰符 synchronized 返回值类型 方法名称(参数列表...) {
                ...
            }


        3.注意:
            (1){}: 所有操作共享数据的代码,都要写在{}中
            (2)同步方法,是否具有锁对象?
                必须有: this 代表调用方法的对象

 */
public class MyTickets implements Runnable{
    //因为100张票,被3个线程共享使用,所以定义在成员位置
    private int tickets = 100;

    @Override
    public void run() {
        //死循环
        while(true) {
            //调用同步方法,完成卖票
            sellTicketsA();
            //调用普通方法,里面是同步代码块
            //sellTicketsB();
        }
    }
  /*  //定义同步方法: 锁对象是this
    public synchronized void sellTicketsA() {
        //(1)判断是否有票
        if(tickets>0) {
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //(2)有: 出一张票
            System.out.println("窗口: "+Thread.currentThread().getName()+" 卖出第: "+tickets+" 张票....");
            //(3)减少一张票
            tickets--;
        }
    }*/
    //定义普通方法,里面使用同步代码块
    public void sellTicketsB() {
        synchronized(this) {
            //(1)判断是否有票
            if(tickets>0) {
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //(2)有: 出一张票
                System.out.println("窗口: "+Thread.currentThread().getName()+" 卖出第: "+tickets+" 张票....");
                //(3)减少一张票
                tickets--;
            }
        }
    }

    //定义自定义方法
    public  synchronized  void  sellTicketsA(){
        if(tickets>0){
            try{
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口: "+Thread.currentThread().getName()+" 卖出第: "+tickets+" 张票....");
            tickets--;
        }
    }
}
